package base_util

import (
	"github.com/gin-gonic/gin"
	"go-likaladi-shop/common/base_global"
	"go.uber.org/zap"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"net/http"
)

// IsGrpcExitError 用于检查 gRPC 调用是否发生错误，并根据错误类型返回适当的 HTTP 响应。
// 参数：
// - err: 需要检查的错误对象。
// - c: Gin 上下文，用于返回 HTTP 响应。
// - errorMsg: 记录错误日志的自定义消息。
// 返回值：
// - bool: 如果发生错误，返回 true；否则返回 false。
func IsGrpcExitError(err error, c *gin.Context, errorMsg string) bool {
	// 如果错误为 nil，表示没有错误，直接返回 false
	if err == nil {
		return false
	}

	// 记录错误日志，包含自定义错误消息和错误详细信息
	zap.S().Errorw(errorMsg, "错误消息", err.Error())

	// 检查错误是否是 gRPC 错误
	if e, ok := status.FromError(err); ok {
		if e.Code() >= base_global.CustomErrorCode {
			// 处理自定义 gRPC 错误码
			RespError(e.Message(), c)
		} else {
			switch e.Code() {
			case codes.Code(base_global.CustomErrorCode):
				// 处理自定义 gRPC 错误码
				RespError(e.Message(), c)
			case codes.NotFound:
				// 资源未找到，返回 HTTP 404
				HttpCodeError(http.StatusNotFound, e.Message(), c)
			case codes.Internal:
				// 内部服务器错误，返回 HTTP 500
				HttpCodeError(http.StatusInternalServerError, "服务内部错误", c)
			case codes.Unavailable:
				// 服务不可用，返回 HTTP 503
				HttpCodeError(http.StatusServiceUnavailable, "服务不可用", c)
			case codes.InvalidArgument:
				// 参数错误，返回 HTTP 400
				HttpCodeError(http.StatusBadRequest, "参数错误", c)
			default:
				// 其他错误，返回 HTTP 500
				HttpCodeError(http.StatusInternalServerError, "其他错误", c)
			}
		}
	}

	// 发生错误，返回 true
	return true
}

// respResult 统一封装 API 响应结构。
// 参数：
// - httpCode: HTTP 状态码。
// - code: 业务错误码（可以是 HTTP 状态码，也可以是自定义错误码）。
// - obj: 具体的响应数据。
// - msg: 响应消息（成功或错误的描述信息）。
// - ctx: gin 上下文对象，用于返回 HTTP 响应。
func respResult(httpCode, code int, obj any, msg any, ctx *gin.Context) {
	ctx.JSON(httpCode, gin.H{
		"code": code, // 业务状态码
		"data": obj,  // 具体返回数据
		"msg":  msg,  // 提示信息
	})
}

// HttpCodeError 用于返回 HTTP 错误响应。
// 参数：
// - httpCode: HTTP 状态码，例如 400, 404, 500。
// - errorMsg: 错误信息，可以是字符串或 JSON。
// - ctx: gin 上下文对象，用于返回 HTTP 响应。
func HttpCodeError(httpCode int, errorMsg any, ctx *gin.Context) {
	ctx.JSON(httpCode, gin.H{
		"error": errorMsg, // 错误信息
	})
}

func HttpError(errorMsg any, ctx *gin.Context) {
	HttpCodeError(http.StatusInternalServerError, errorMsg, ctx)
}

// RespSuccess 返回成功的 HTTP 响应。
// 参数：
// - obj: 具体的响应数据。
// - ctx: gin 上下文对象，用于返回 HTTP 响应。
func RespSuccess(obj any, ctx *gin.Context) {
	respResult(http.StatusOK, http.StatusOK, obj, "success", ctx)
}

// RespCodeError 用于返回带有自定义错误码的 HTTP 响应。
// 参数：
// - code: 业务错误码，例如 1001, 1002。
// - errorMsg: 错误信息。
// - ctx: gin 上下文对象，用于返回 HTTP 响应。
func RespCodeError(code int, errorMsg any, ctx *gin.Context) {
	respResult(http.StatusOK, code, nil, errorMsg, ctx)
}

// RespError 返回 HTTP 500 内部错误。
// 参数：
// - errorMsg: 错误信息。
// - ctx: gin 上下文对象，用于返回 HTTP 响应。
func RespError(errorMsg any, ctx *gin.Context) {
	respResult(http.StatusOK, http.StatusInternalServerError, nil, errorMsg, ctx)
}
